﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web;
using Medianamik.Core.Interfaces;

namespace Medianamik.Core.Resources
{
    public class MedianamikAssemblyCollection : ICollection<IMedianamikAssembly>
    {
        private static short _counter = 0;
        private SortedList<int, IMedianamikAssembly> _assemblies;
        protected SortedList<int, IMedianamikAssembly> Assemblies
        {
            get
            {
                return _assemblies
                    ?? (_assemblies = new SortedList<int, IMedianamikAssembly>());
            }
        }

        public MedianamikAssemblyCollection()
        { }

        public MedianamikAssemblyCollection(IEnumerable<IMedianamikAssembly> pAssemblies)
        {
            foreach (var item in pAssemblies)
            {
                Add(item);
            }
        }

        public virtual bool IsPathVirtual(string pPath)
        {
            IMedianamikAssembly dummy;
            return IsPathVirtual(pPath, out dummy);
        }
        public virtual bool IsPathVirtual(string pPath, out IMedianamikAssembly pAssembly)
        {
            string checkPath = VirtualPathUtility.ToAppRelative(pPath);
            pAssembly = null;
            bool result = false;
            for (int i = 0; i < Assemblies.Count; i++)
            {
                if (Assemblies.Values[i].IsPathVirtual(pPath))
                {
                    result = true;
                    pAssembly = Assemblies.Values[i];
                    break;
                }
            }
            return result;
        }

        public void Add(IMedianamikAssembly item)
        {
            //on crée une clé pour l'item.
            //Plus son Depth est grand, plus sa clé sera petite
            int key = int.MaxValue - ((_counter++) ^ (item.Depth << 16));
            Assemblies.Add(key, item);
        }

        void ICollection<IMedianamikAssembly>.Clear()
        {
            Assemblies.Clear();
        }

        bool ICollection<IMedianamikAssembly>.Contains(IMedianamikAssembly item)
        {
            return Assemblies.ContainsValue(item); 
        }

        void ICollection<IMedianamikAssembly>.CopyTo(IMedianamikAssembly[] array, int arrayIndex)
        {
            if (array == null)
            {
                throw new ArgumentNullException("array");
            }
            if ((arrayIndex < 0) || (arrayIndex > array.Length))
            {
                throw new ArgumentOutOfRangeException("arrayIndex");
            }
            if ((array.Length - arrayIndex) < this.Count)
            {
                throw new ArgumentException("array is too small");
            }
            for (int i = 0; i < this.Count; i++)
            {
                array[arrayIndex + i] = this.Assemblies[i];
            }

        }

        public int Count
        {
            get { return this.Assemblies.Count; }
        }

        bool ICollection<IMedianamikAssembly>.IsReadOnly
        {
            get { return false; }
        }

        bool ICollection<IMedianamikAssembly>.Remove(IMedianamikAssembly item)
        {
            return Assemblies.Values.Remove(item);
        }

        IEnumerator<IMedianamikAssembly> IEnumerable<IMedianamikAssembly>.GetEnumerator()
        {
            return Assemblies.Values.GetEnumerator();
        }

        System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
        {
            return Assemblies.Values.GetEnumerator();
        }
    }
}
